home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Games / warp / weapon.c < prev    next >
C/C++ Source or Header  |  1995-05-03  |  17KB  |  689 lines

  1. /* $Header: weapon.c,v 7.0.1.2 86/10/20 14:36:33 lwall Exp $ */
  2.  
  3. /* $Log:    weapon.c,v $
  4.  * Revision 7.0.1.2  86/10/20  14:36:33  lwall
  5.  * Picked some lint.
  6.  * 
  7.  * Revision 7.0.1.1  86/10/16  10:54:42  lwall
  8.  * Added Damage.  Fixed random bugs.
  9.  * 
  10.  * Revision 7.0  86/10/08  15:18:08  lwall
  11.  * Split into separate files.  Added amoebas and pirates.
  12.  * 
  13.  */
  14.  
  15. #include "EXTERN.h"
  16. #include "warp.h"
  17. #include "bang.h"
  18. #include "object.h"
  19. #include "move.h"
  20. #include "score.h"
  21. #include "sig.h"
  22. #include "term.h"
  23. #include "them.h"
  24. #include "us.h"
  25. #include "util.h"
  26. #include "INTERN.h"
  27. #include "weapon.h"
  28.  
  29. void
  30. weapon_init()
  31. {
  32.     ;
  33. }
  34.  
  35. void
  36. fire_torp(from, ydir, xdir)
  37. Reg1 OBJECT *from;
  38. Reg3 int ydir;
  39. Reg4 int xdir;
  40. {
  41.     Reg2 OBJECT *to;
  42.  
  43.     if (from->type == Enemy ||
  44.        (from == ent && etorp > 0) ||
  45.        (from == base && btorp > 0)) {
  46.     to = occupant[(from->posy+from->vely+ydir+YSIZE00)%YSIZE]
  47.              [(from->posx+from->velx+xdir+XSIZE00)%XSIZE];
  48.     if (from->type != Enemy || !to || to->vely || to->velx) {
  49.         if (from->type != Enemy &&
  50.          (to = isatorp[from==base][ydir+1][xdir+1])) {
  51.         to->vely += ydir;
  52.         to->velx += xdir;
  53.         }
  54.         else {
  55.         if (from == ent) {
  56.             to = make_object(Torp, '+', from->posy,from->posx,
  57.             from->vely+ydir,from->velx+xdir, 0L, 1L,&root);
  58.             aretorps++;
  59.             isatorp[0][ydir+1][xdir+1] = to;
  60.             etorp--;
  61.         }
  62.         else if (from == base) {
  63.             to = make_object(Torp, '+', from->posy,from->posx,
  64.             from->vely+ydir,from->velx+xdir, 0L, 1L,&root);
  65.             aretorps++;
  66.             isatorp[1][ydir+1][xdir+1] = to;
  67.             btorp--;
  68.         }
  69.         else if (from->image == 'G') {
  70.             numos++;
  71.             to = make_object(Torp, 'o', from->posy,from->posx,
  72.             from->vely+ydir,from->velx+xdir, 100L, 1L,&root);
  73.             if (madgorns) {
  74.             possiblescore += 35;
  75.             to->image = '0';
  76.             to->mass = 2000;
  77.             to->energy = 2000;
  78.             }
  79.             else if (rand_mod(120)+10 > smarts)
  80.             possiblescore += 100;
  81.             else {
  82.             possiblescore += 200;
  83.             to->image = 'O';
  84.             }
  85.         }
  86.         else {
  87.             to = make_object(Torp, 'x', from->posy,from->posx,
  88.             from->vely+ydir,from->velx+xdir, 0L, 1L,&root);
  89.             if (rand_mod(160)+10 > smarts)
  90.             possiblescore += 10;
  91.             else {
  92.             possiblescore += 100;
  93.             to->image = 'X';
  94.             to->mass = 1000+super*20;
  95.             numxes++;
  96.             }
  97.         }
  98.         }
  99.     }
  100.     }
  101. }
  102.  
  103. void
  104. attack(attackee)
  105. Reg7 OBJECT *attackee;
  106. {
  107.     Reg1 int dx;
  108.     Reg2 int dy;
  109.     Reg3 int curx;
  110.     Reg4 int cury;
  111.     Reg5 int prob;
  112.     Reg6 OBJECT *obj;
  113.     Reg8 bool torps;
  114.     Reg9 bool webnear = FALSE;
  115.     Reg10 bool thru_stars;
  116.     int nukey;
  117.     int nukex;
  118.     int nukedist;
  119.  
  120.     if (attackee) {
  121.     if (attackee == nuke) {
  122.         if (amb[attackee->posy][attackee->posx] != '~')
  123.         return;
  124.         nukey = nukex = 0;
  125.         nukedist = 100;
  126.     }
  127.     for (dx= -1; dx<=1 ; dx++) {
  128.         for (dy= -1; dy<=1; dy++) {
  129.         if (dx||dy) {
  130.             cury = attackee->posy;
  131.             curx = attackee->posx;
  132.             torps = thru_stars = FALSE;
  133.             if (massacre || madgorns || !rand_mod(53-super) )
  134.             webnear += rand_mod(2);
  135.             else
  136.             webnear = FALSE;
  137.             for (prob = scandist;prob;prob--) {
  138.             cury = (cury + dy + YSIZE00) % YSIZE;
  139.             curx = (curx + dx + XSIZE00) % XSIZE;
  140.             if (obj = occupant[cury][curx]) {
  141.                 switch (obj->image) {
  142.                 case 'P': case 'K': case 'R': case ' ':
  143.         pot_shot:
  144.                 if (attackee == nuke) {
  145.                     if (rand_mod(2+scandist-prob) <
  146.                       rand_mod(smarts/40+1))
  147.                     Tract(nuke,dy,dx,rand_mod(3)?1:-1);
  148.                 }
  149.                 if (rand_mod(51 - sm50) <= prob) {
  150.                     switch (obj->strategy||thru_stars?0:
  151.                       rand_mod(ent?4:2)) {
  152.                     case 1: case 2:
  153.                     if (-dy + attackee->vely == obj->vely
  154.                      && -dx + attackee->velx == obj->velx)
  155.                         fire_torp(obj,
  156.                          -dy + attackee->vely,
  157.                          -dx + attackee->velx);
  158.                     else
  159.                         fire_torp(obj,
  160.                          -dy + attackee->vely - obj->vely,
  161.                          -dx + attackee->velx - obj->velx);
  162.                     if (obj->image == ' ')
  163.                         setimage(obj,
  164.                           obj->flags & PIRATE ? 'P' : 'R');
  165.                     break;
  166.                     case 3: {
  167.                     int newspeed =
  168.                         rand_mod(prob<5&&smarts>70?4:3)-1;
  169.                     
  170.                     obj->vely = -dy * newspeed;
  171.                     obj->velx = -dx * newspeed;
  172.                     if (newspeed >= 0 &&
  173.                         !rand_mod(82-sm80)) {
  174.                         obj->vely += attackee->vely;
  175.                         obj->velx += attackee->velx;
  176.                     }
  177.                     break;
  178.                     }
  179.                     case 0:
  180.                     if (!torps && obj->energy > 1000) {
  181.                         fire_phaser(obj, -dy, -dx);
  182.                         if (smarts > 40 &&
  183.                            (scandist-prob > 5
  184.                         || attackee==base) &&
  185.                            (massacre || obj->strategy ||
  186.                             rand_mod(2)))
  187.                         while (rand_mod(2))
  188.                             fire_phaser(obj, -dy, -dx);
  189.                         if (obj->image == ' ')
  190.                         setimage(obj,
  191.                           obj->flags&PIRATE ? 'P':'R');
  192.                     }
  193.                     if (obj->strategy) {
  194.                         obj->velx = obj->vely = 0;
  195.                         if (obj->energy < 1000 ||
  196.                           bvely || bvelx)
  197.                         obj->strategy = 0;
  198.                     }
  199.                     else if ((attackee==base ||
  200.                           (cloaking && attackee==ent)
  201.                          ) &&
  202.                          scandist-prob > 5 &&
  203.                              !(rand_mod(
  204.                            ent?antibase*2:antibase)) )
  205.                         obj->strategy = 1;
  206.                     break;
  207.                     }
  208.                 }
  209.                 goto bombout;
  210.                 case 'G':
  211.                 if (thru_stars && obj->strategy < 7)
  212.                     goto bombout;
  213.                 if (attackee == nuke) {
  214.                     if (rand_mod(2+scandist-prob) <
  215.                       rand_mod(smarts/40+1))
  216.                     Tract(nuke,dy,dx,rand_mod(3)?1:-1);
  217.                     goto bombout;
  218.                 }
  219.                 if (obj->strategy) {
  220.                     if (madgorns || !rand_mod(4)) {
  221.                     obj->vely = attackee->vely;
  222.                     obj->velx = attackee->velx;
  223.                     }
  224.                     obj->strategy += (!torps && deados > 10);
  225.                     if (obj->strategy > 4)
  226.                     madgorns = TRUE;
  227.                     if (!torps && obj->strategy > 5) {
  228.                     do {
  229.                         fire_phaser(obj, -dy, -dx);
  230.                     } while (rand_mod(2));
  231.                     }
  232.                 }
  233.                 else if (numgorns >= numenemies-1 &&
  234.                     deados > 15+numgorns*5)
  235.                     obj->strategy = 1;
  236.                 if (madgorns || rand_mod(51 - sm50) <= prob) {
  237.                     if (-dy + attackee->vely == obj->vely
  238.                      && -dx + attackee->velx == obj->velx)
  239.                     fire_torp(obj,
  240.                      -dy + attackee->vely,
  241.                      -dx + attackee->velx);
  242.                     else
  243.                     fire_torp(obj,
  244.                      -dy + attackee->vely - obj->vely,
  245.                      -dx + attackee->velx - obj->velx);
  246.                 }
  247.                 goto bombout;
  248.                 case 'T':
  249.                 if (attackee == nuke) {
  250.                     if (rand_mod(2+scandist-prob) <
  251.                       rand_mod(smarts/40+1))
  252.                     Tract(nuke,dy,dx,rand_mod(3)?1:-1);
  253.                 }
  254.                 if (thru_stars)
  255.                     goto bombout;
  256.                 if (webnear && scandist-prob > 5) {
  257.                     if (massacre || rand_mod(50) < super) {
  258.                     if (!torps && obj->energy > 1000) {
  259.                         fire_phaser(obj, -dy, -dx);
  260.                         while (!rand_mod(57-sm55))
  261.                         fire_phaser(obj, -dy, -dx);
  262.                     }
  263.                     }
  264.                 }
  265.                 goto bombout;
  266.                 case 'C': case 'c':
  267.                 if (thru_stars)
  268.                     goto bombout;
  269.                 break;
  270.                 case 'Q': case 'W': case 'Y': case 'U':
  271.                 case 'I': case 'S': case 'D': case 'H': case 'J':
  272.                 case 'L': case 'Z': case 'V': case 'M': case 'F':
  273.                 if (attackee == nuke) {
  274.                     if (rand_mod(2+scandist-prob) <
  275.                       rand_mod(smarts/40+1))
  276.                     Tract(nuke,dy,dx,rand_mod(3)?1:-1);
  277.                     if (rand_mod(2))
  278.                     goto pot_shot;
  279.                 }
  280.                 if (madfriends > 1000) {
  281.                     madfriends -= 200;
  282.                     goto pot_shot;
  283.                 }
  284.                 /* FALL THROUGH */
  285.                 case '+':
  286.                 if (attackee == nuke) {
  287.                     if (smarts > 70) {
  288.                     if (
  289.                      (obj->posx + obj->velx + XSIZE00)%XSIZE
  290.                         == attackee->posx &&
  291.                      (obj->posy + obj->vely + YSIZE00)%YSIZE
  292.                         == attackee->posy ) {
  293.                         Tract(nuke,dy,dx,-1);
  294.                     }
  295.                     else
  296.                         while (!rand_mod(82-sm80))
  297.                         Tract(nuke,dy,dx,-1);
  298.                     }
  299.                     else if (smarts > 60 ||
  300.                       rand_mod(2+scandist-prob) <
  301.                       rand_mod(smarts/20+1))
  302.                     Tract(nuke,dy,dx,rand_mod(3)?1:-1);
  303.                 }
  304.                 torps = FALSE;
  305.                 thru_stars = FALSE;
  306.                 break;
  307.                 case '|': case '-': case '/': case '\\':
  308.                 if (thru_stars)
  309.                     goto bombout;
  310.                 webnear = (scandist-prob < 3);
  311.                 torps = FALSE;
  312.                 break;
  313.                 case 'x':
  314.                 if (attackee == nuke) {
  315.                     if (rand_mod(2+scandist-prob) <
  316.                       rand_mod(smarts/20+1))
  317.                     Tract(nuke,dy,dx,rand_mod(3)?1:-1);
  318.                 }
  319.                 if (thru_stars)
  320.                     goto bombout;
  321.                 torps = TRUE;
  322.                 break;
  323.                 case 'o': case 'O': case '0':
  324.                 if (attackee == nuke) {
  325.                     if (rand_mod(2+scandist-prob) <
  326.                       rand_mod(smarts/20+1))
  327.                     Tract(nuke,dy,dx,rand_mod(3)?1:-1);
  328.                 }
  329.                 if (thru_stars)
  330.                     goto bombout;
  331.                 torps = TRUE;
  332.                 if (rand_mod(99+3*scandist) < smarts+3*prob) {
  333.                     obj->vely = -dy + attackee->vely;
  334.                     obj->velx = -dx + attackee->velx;
  335.                     if (obj->flags & STATIC) {/* not a mover? */
  336.                     obj->flags &= ~STATIC;
  337.                     obj->prev->next = obj->next;
  338.                     obj->next->prev = obj->prev;
  339.                     root.prev->next = obj;
  340.                     obj->prev = root.prev;
  341.                     root.prev = obj;
  342.                     obj->next = &root;
  343.                     }
  344.                 }
  345.                 if (obj->image != '0')
  346.                     break;
  347.                 /* DROP THROUGH! */
  348.                 case 'X':
  349.                 if (attackee == nuke) {
  350.                     if (rand_mod(2+scandist-prob) <
  351.                       rand_mod(smarts/20+1))
  352.                     Tract(nuke,dy,dx,rand_mod(3)?1:-1);
  353.                 }
  354.                 torps = TRUE;
  355.                 if (thru_stars)
  356.                     goto bombout;
  357.                 if (prob == scandist) {
  358.                     int y, x;
  359.  
  360.                     blast[y=(obj->posy+obj->vely+YSIZE00)%YSIZE]
  361.                      [x=(obj->posx+obj->velx+XSIZE00)%XSIZE]
  362.                       += (obj->image == '0' ? 2000 : 200);
  363.                     yblasted[y] |= 1;
  364.                     xblasted[x] |= 1;
  365.                     blasted = TRUE;
  366.                 }
  367.                 break;
  368.                 case 'A':
  369.                 if (attackee != nuke) {
  370.                     if (scandist-prob>1 && !rand_mod(51-super))
  371.                     Tract(obj,-dy,-dx,1);
  372.                 }
  373.                 /* FALL THROUGH */
  374.                 case '*': case '@':
  375.                 if (attackee == nuke) {
  376.                     if (amb[cury][curx] != '~') {
  377.                     if (scandist-prob < nukedist) {
  378.                         nukedist = scandist-prob;
  379.                         nukey = dy;    /* nearest food in */
  380.                         nukex = dx;    /*   this direction */
  381.                     }
  382.                     if (smarts > 55 && scandist-prob > 8) {
  383.                         if (rand_mod(30+scandist-prob) <
  384.                           rand_mod(smarts/20+1))
  385.                         Tract(nuke,dy,dx,1);
  386.                     }
  387.                     }
  388.                     else if (obj->vely || obj->velx) {
  389.                     Tract(nuke,dy,dx,1); /* for looks */
  390.                     obj->vely = obj->velx = 0;
  391.                     }
  392.                 }
  393.                 if (!thru_stars)
  394.                     if (rand_mod(97-sm95))
  395.                     goto bombout;
  396.                     else
  397.                     thru_stars = TRUE;
  398.                 break;
  399.                 case '<': case '>':
  400.                 if (attackee == nuke) {
  401.                     if ((!dy && scandist-prob < 8) ||
  402.                       rand_mod(2+scandist-prob) <
  403.                       rand_mod(smarts/20+1) ) {
  404.                     nuke->mass += 10000;
  405.                     Tract(nuke,dy,dx,-1);
  406.                     nuke->mass -= 10000;
  407.                     }
  408.                 }
  409.                 goto bombout;
  410.                 case 'E': case 'B':
  411.                 if (attackee == nuke) {
  412.                     if (rand_mod(2+scandist-prob) <
  413.                       rand_mod(smarts/40+1))
  414.                     Tract(nuke,dy,dx,rand_mod(3)?1:-1);
  415.                 }
  416.                 goto bombout;
  417.                 default:
  418.                 goto bombout;
  419.                 }
  420.             }
  421.             else {
  422.                 if (thru_stars)
  423.                 goto bombout;
  424.             }    
  425.             }
  426. bombout:            ; /* end of loop */
  427.         }
  428.         }
  429.     }
  430.     if (attackee == nuke && nukedist < 100) {/* aim amoeba at nearest */
  431.         if (nukey < 0)            /*   free star */
  432.         nukey = 2;
  433.         if (nukex < 0)
  434.         nukex = 2;
  435.         nuke->strategy = nukey + (nukex << 2);
  436.     }
  437.     }
  438. }
  439.  
  440. void
  441. fire_phaser(obj, dy, dx)
  442. Reg7 OBJECT *obj;
  443. Reg5 int dy;
  444. Reg6 int dx;
  445. {
  446.     Reg1 int y;
  447.     Reg2 int x;
  448.     Reg3 int skipping;
  449.     Reg4 int size=5000;
  450.     int decr = 50, oldy, oldx;
  451.     static char curchar[] = "@* ";
  452.  
  453.     if (obj == ent)
  454.     decr = 100;
  455.     else if (obj == base) {
  456.     decr = 1000;
  457.     size = 200;
  458.     }
  459.     if (!dy)
  460.     curchar[2] = '-';
  461.     else if (!dx)
  462.     curchar[2] = '!';
  463.     else if (dy == dx)
  464.     curchar[2] = '\\';
  465.     else
  466.     curchar[2] = '/';
  467.     if (obj->energy >= decr) {
  468.     obj->energy -= decr;
  469.     for (
  470.       /* initialize */
  471.       skipping = (obj != base),
  472.       y = (obj->posy+(obj==base?dy*2:dy)+YSIZE00)%YSIZE,
  473.       x = (obj->posx+(obj==base?dx*2:dx)+XSIZE00)%XSIZE;
  474.       /* while */
  475.       size && (!occupant[y][x]||(skipping && occupant[y][x]->type==Star));
  476.       /* at end of loop */
  477.       y = (y+dy+YSIZE00) % YSIZE,
  478.       x = (x+dx+XSIZE00) % XSIZE,
  479.       size = size * 3 / 4 ) {
  480.         move(y+1,x*2,0);
  481.         beg_qwrite();
  482.         if (obj == base || obj->image == 'T') {
  483.         *filler = '@';
  484.         qwrite();
  485.         *filler = '#';
  486.         qwrite();
  487.         *filler = '~';
  488.         qwrite();
  489.         *filler = '%';
  490.         qwrite();
  491.         *filler = ':';
  492.         qwrite();
  493.         *filler = '@';
  494.         }
  495.         else {
  496.         *filler = size >= 500 ?
  497.               *curchar : (size >= 50 ?
  498.                      curchar[1] :
  499.                      curchar[2]);
  500.         }
  501.         qwrite();
  502.         if (occupant[y][x])
  503.         qaddc(occupant[y][x]->image);
  504.         else {
  505.         if (numamoebas)
  506.             qaddc(amb[y][x]);
  507.         else
  508.             qaddspace();
  509.         if (skipping)
  510.             skipping = 0;
  511.         }
  512.         end_qwrite();
  513.     }
  514.     if (size) {
  515.         char img;
  516.  
  517.         assert(occupant[y][x]);
  518.         img = occupant[y][x]->image;
  519.         if (occupant[y][x]->type == Crusher) {
  520.         if (dy)
  521.             return;
  522.             if (dx==(img == '<' ? 1 : -1) ) {
  523.             occupant[y][x]->image =
  524.             (occupant[y][x]->velx *= -1) < 0 ? '>' : '<';
  525.             return;
  526.         }
  527.         }
  528.         else if (occupant[y][x]->flags & FRIENDLY)
  529.         madfriends += 200;
  530.         if (numamoebas && amb[y][x] == '~' && smarts % 3 &&
  531.         (smarts > 70 || rand_mod(smarts) > rand_mod(20)) ) {
  532.         if (size > 10000)
  533.             modify_amoeba(y,x,1,'~',10);
  534.         else if (size > 1000)
  535.             modify_amoeba(y,x,1,'~',7);
  536.         else if (size > 50)
  537.             modify_amoeba(y,x,1,'~',5);
  538.         else
  539.             modify_amoeba(y,x,1,'~',2);
  540.         if (occupant[y][x] == nuke) {
  541.             nuke->strategy = rand_mod(30);
  542.             nuke->flags |= COUNTDOWN;
  543.         }
  544.         return;
  545.         }
  546.         else {
  547.         move(y+1,x*2,0);
  548.         beg_qwrite();
  549.         if (img == ' ') {
  550.             *filler = occupant[y][x]->flags & PIRATE ? 'P' : 'R';
  551.             occupant[y][x]->image = *filler;
  552.             occupant[y][x]->strategy = 0;
  553.             qwrite();
  554.             qwrite();
  555.         }
  556.         else if (img == 'C' || img == 'c') {
  557.             cloaked = 0;
  558.             img += 2;
  559.             occupant[y][x]->image = img;
  560.             *filler = img;
  561.             qwrite();
  562.             qwrite();
  563.         }
  564.         else if (img == 'K' && size > 50)
  565.             occupant[y][x]->strategy = 0;
  566.         *filler = '@';
  567.         qwrite();
  568.         *filler = '#';
  569.         qwrite();
  570.         *filler = '@';
  571.         qwrite();
  572.         *filler = '#';
  573.         qwrite();
  574.         *filler = '@';
  575.         qwrite();
  576.         qaddc(img);
  577.         end_qwrite();
  578.         oldy = y;
  579.         oldx = x;
  580.         y = (occupant[oldy][oldx]->posy + occupant[oldy][oldx]->vely +
  581.             YSIZE00) % YSIZE;
  582.         x = (occupant[oldy][oldx]->posx + occupant[oldy][oldx]->velx +
  583.             XSIZE00) % XSIZE;
  584.         if (occupant[y][x] && occupant[y][x]->type == Star) {
  585.             y = occupant[oldy][oldx]->posy;
  586.             x = occupant[oldy][oldx]->posx;
  587.         }
  588.         if (obj==base)
  589.             blast[y][x] += size>50 ? 15000 : (size>15 ? 1500 : 150);
  590.         else if (obj==ent)
  591.             blast[y][x] += size*4;
  592.         else if (obj->image=='T')
  593.             blast[y][x] += 15000;
  594.         else
  595.             blast[y][x] += size*smarts/25;
  596.         yblasted[y] |= 1;
  597.         xblasted[x] |= 1;
  598.         blasted = TRUE;
  599.         }
  600.     }
  601.     }
  602. }
  603.  
  604. int
  605. tract(obj, dy, dx, to_or_fro)
  606. Reg7 OBJECT *obj;
  607. Reg4 int dy;
  608. Reg5 int dx;
  609. int to_or_fro;
  610. {
  611.     Reg1 int y;
  612.     Reg2 int x;
  613.     Reg3 int size=10;
  614.     static char ch;
  615.     Reg6 OBJECT *tractee;
  616.  
  617.     if (!dy)
  618.     ch = '|';
  619.     else if (!dx)
  620.     ch = '-';
  621.     else if (dy == dx)
  622.     ch = '/';
  623.     else
  624.     ch = '\\';
  625.     {
  626.     for (
  627.       y = (obj->posy+dy+YSIZE00)%YSIZE,
  628.       x = (obj->posx+dx+XSIZE00)%XSIZE;
  629.       size && (!occupant[y][x]);
  630.       y = (y+dy+YSIZE00) % YSIZE, x = (x+dx+XSIZE00) % XSIZE, size--) {
  631.         move(y+1,x*2,0);
  632.         beg_qwrite();
  633.         *filler = ch;
  634.         qwrite();
  635.         qwrite();
  636.         if (numamoebas)
  637.         qaddch(amb[y][x]);
  638.         else
  639.         qaddspace();
  640.         end_qwrite();
  641.     }
  642.     tractee = occupant[y][x];
  643.     if (size) {
  644.         assert(tractee);
  645.         if (numamoebas && obj != nuke && amb[y][x] == '~') {
  646.         if (to_or_fro > 0)
  647.             modify_amoeba(y,x,2,'~',size);
  648.         else
  649.             modify_amoeba(y,x,1,' ',size);
  650.         }
  651.         if (tractee->type != Web &&
  652.         (tractee->mass < obj->mass * 5 ||
  653.          (tractee->type == Crusher && !dx) ) ) {
  654.         if (tractee == ent) {
  655.             evely -= dy * to_or_fro;
  656.             evelx -= dx * to_or_fro;
  657.         }
  658.         else if (tractee == base) {
  659.             bvely -= dy * to_or_fro;
  660.             bvelx -= dx * to_or_fro;
  661.         }
  662.         else {
  663.             tractee->vely -= dy * to_or_fro;
  664.             tractee->velx -= dx * to_or_fro;
  665.         }
  666.         if (tractee->type == Torp ||
  667.             tractee->type == Star) {
  668.             if (tractee->flags & STATIC) {  /* not a mover? */
  669.             tractee->flags &= ~STATIC;
  670.             tractee->prev->next = tractee->next;
  671.             tractee->next->prev = tractee->prev;
  672.             root.prev->next = tractee;
  673.             tractee->prev = root.prev;
  674.             root.prev = tractee;
  675.             tractee->next = &root;
  676.             }
  677.         }
  678.         }
  679.         else if (tractee->type == Crusher && !dy &&
  680.           dx==(tractee->image == '<' ? 1 : -1) ) {
  681.         setimage(tractee, (tractee->velx *= -1) < 0 ? '>' : '<');
  682.         }
  683.         if (tractee->mass * 5 > obj->mass)
  684.         return(1);
  685.     }
  686.     }
  687.     return(0);
  688. }
  689.